package com.ant.storage.handler;

import com.ant.storage.common.ResultCode;
import com.ant.storage.common.ResultVo;
import com.ant.storage.pojo.ErrMsg;
import com.ant.storage.service.IErrMsgService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

import javax.servlet.http.HttpServletRequest;
import java.sql.SQLException;
import java.util.Date;


/**
 * @author hzd
 * @version 1.0
 * @date 2022/3/16 14:13
 */
@Slf4j
//@ControllerAdvice
@RestControllerAdvice
public class GlobalExceptionHandler {
    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @Autowired
    IErrMsgService errMsgService;
    /**
     * 处理自定义的业务异常
     * @param request
     * @param e
     * @return
     */
    @ExceptionHandler(AntException.class)
    @ResponseBody
    public ResultVo CustomExceptionHandler(HttpServletRequest request, AntException e){
        logger.error("发生业务异常！原因是：{}",e.getErrorMsg());
        return ResultVo.failure(e.getErrorCode(),e.getErrorMsg());
    }

    /**
     * 处理空指针的异常
     * @param request
     * @param e
     * @return
     */
    @ExceptionHandler(value =NullPointerException.class)
    @ResponseBody
    public ResultVo exceptionHandler(HttpServletRequest request, NullPointerException e){
        logger.error("发生空指针异常！原因是:",e);
        return ResultVo.fail(ResultCode.PARAM_IS_BLANK);
    }

    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public ResultVo handleMaxUploadSizeExceededException(MaxUploadSizeExceededException ex) {
        logger.error(ex.getMessage());
//        String msg;
//        if (ex.getCause().getCause() instanceof FileSizeLimitExceededException) {
//            logger.error(ex.getMessage());
//            msg = ResultCode.NOT_FOUND_IMG + "[单文件大小不得超过100M]";
//        } else if (ex.getCause().getCause() instanceof SizeLimitExceededException) {
//            logger.error(ex.getMessage());
//            msg = ResultCode.NOT_FOUND_IMG + "[总上传文件大小不得超过200M]";
//        } else {
//            msg = ResultCode.NOT_FOUND_IMG + "请检查文件类型及大小是否符合规范";
//        }
        return ResultVo.failure(ResultCode.NOT_FOUND_IMG.getResultCode(),ResultCode.NOT_FOUND.getResultMsg);
    }

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler({IllegalArgumentException.class})
    public ResultVo badRequestException(IllegalArgumentException e) {
        return ResultVo.fail(ResultCode.FAILURE);
    }

    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler({SQLException.class})
    @ResponseBody
    public ResultVo handleSQLException(SQLException e) {
       // return defHandler("服务运行SQLException异常", e);
        return ResultVo.fail(ResultCode.SQL_INTERNAL_SERVER_ERROR);
    }


    /**
     * 验证参数异常错误
     * @param ex
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    public ResultVo handle2(MethodArgumentNotValidException ex){
        BindingResult bindingResult = ex.getBindingResult();
        if(bindingResult!=null){
            if(bindingResult.hasErrors()){
                FieldError fieldError = bindingResult.getFieldError();
                String field = fieldError.getField();
                String defaultMessage = fieldError.getDefaultMessage();
                logger.error(ex.getMessage(),ex);
                return ResultVo.fail(defaultMessage);
            }else {
                logger.error(ex.getMessage(),ex);
                return new ResultVo(ResultCode.FAILURE);
            }
        }else {
            logger.error(ex.getMessage(),ex);
            return new ResultVo(ResultCode.FAILURE);
        }
    }

    /**
     * 处理其他异常
     * @param request
     * @param e
     * @return
     */
    @ExceptionHandler(value =Exception.class)
    @ResponseBody
    public ResultVo exceptionHandler(HttpServletRequest request, Exception e){
        logger.error("未知异常！原因是:",e);
        return ResultVo.fail(ResultCode.INTERNAL_SERVER_ERROR);
    }


    /**
     * Http请求消息序列化异常
     * @param e
     * @return
     */
    @ExceptionHandler({HttpMessageNotReadableException.class})
    @ResponseBody
    public ResultVo messageExceptionHandler(HttpServletRequest request,HttpMessageNotReadableException e) {
        log.warn("request: "+ request.getRequestURI());
        log.warn("http请求参数转换异常: "+ e.getMessage());
        ErrMsg msg=new ErrMsg();
        msg.setErrName(request.getRequestURI());
        msg.setErrCode(ResultCode.BODY_NOT_MATCH.getResultCode().toString());
        msg.setRequestMethod(request.getMethod());
        msg.setErrValue(e.getMessage());
        msg.setCreationTime(new Date());
        errMsgService.save(msg);
        return ResultVo.failure(ResultCode.BODY_NOT_MATCH.getResultCode(),
                ResultCode.BODY_NOT_MATCH.getResultMsg+e.getMessage());
    }
}
